#include "cyclical_queue.h"

/**
 * @brief 初始化队列
 * 初始化时，由于队列为空，队列头和尾位置都在0
 * @param queue 队列
 */
void CycQueueInit(CycQueue_t *queue)
{
    queue->front = 0;
    queue->rear = 0;
}

/**
 * @brief 判断队列是否为空
 * 当队列头位置和尾位置相同时，队列为空
 * @param queue 队列
 */
bool CycQueueIsEmpty(const CycQueue_t *queue)
{
    return queue->front == queue->rear;
}

/**
 * @brief 判断队列是否满
 * 牺牲一个队列单元，当 (队列尾+1) = 对列头 时队列为满
 * @param queue 队列
 */
bool CycQueueIsFull(const CycQueue_t *queue)
{
    return (queue->rear + 1) % MAX_QUEUE_LENGTH == queue->front;
}

/**
 * @brief 入队
 * @param queue 队列
 * @param data {@UserInfo_t}
 * @return {@CycQueueStatus_t}
 */
CycQueueStatus_t CycQueueIn(CycQueue_t *queue, const UserInfo_t *data)
{
    if (CycQueueIsFull(queue)) {
        return CYC_QUEUE_FAIL;
    }
    queue->data[queue->rear] = *data;
    queue->rear = (queue->rear + 1) % MAX_QUEUE_LENGTH;
    return CYC_QUEUE_SUCCESS;
}

/**
 * @brief 出队
 * @param queue 队列
 * @param data {@UserInfo_t}
 * @return {@CycQueueStatus_t}
 */
CycQueueStatus_t CycQueueOut(CycQueue_t *queue, UserInfo_t *data)
{
    if (CycQueueIsEmpty(queue)) {
        return CYC_QUEUE_FAIL;
    }
    *data = queue->data[queue->front];
    queue->front = (queue->front + 1) % MAX_QUEUE_LENGTH;
    return CYC_QUEUE_SUCCESS;
}

/**
 * @brief 获取队列头
 * @param queue 队列
 * @param data {@UserInfo_t}
 * @return {@CycQueueStatus_t}
 */
CycQueueStatus_t CycQueueGetFront(const CycQueue_t *queue, UserInfo_t *data)
{
    if (CycQueueIsEmpty(queue)) {
        return CYC_QUEUE_FAIL;
    }
    *data = queue->data[queue->front];
    return CYC_QUEUE_SUCCESS;
}